import base64
from Crypto.Cipher import AES
import re
import collections
from .loggers import dev_logger, record_logger
import sys
import hashlib

# from Crypto.Util.Padding import pad
#
from .aes_algorithm import AES128_UDS


def singleton(cls):
    '''
        单例模式的装饰器
    '''
    instances = {}

    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance


def executor_pool_exception_callback(worker):
    # 将子线程的异常信息记录到日志中
    dev_logger.debug('子线程executor_pool_exception_callback回调函数被调用了')
    # 判断一下子线程是否有异常
    worker_exception = worker.exception()
    if worker_exception:
        dev_logger.warning(f"worker return exception:{worker_exception}")
        record_logger.warning(f"worker return exception:{worker_exception}")


def seed_to_key(positive_resp_data, Learmask=0x5f0f50a1) -> list[int]:
    # seedValue = [int(item, 16) for item in seed.split(' ')[1:]]

    # seed = [int(item, 16) for item in positive_resp_data.split(' ')[1:]]
    seed = positive_resp_data[1:]
    pass
    # print(f'[file:{__file__}]=>[line:{
    #     (sys._getframe().f_lineno)}]==>seed:{seed}')

    seedValue = (seed[0] << 24) | (
        seed[1] << 16) | (seed[2] << 8) | (seed[3])
    # print("seedValue:", hex(seedValue))

    if seedValue != 0:
        for i in range(35):
            if (seedValue & 0x80000000):
                seedValue = seedValue << 1
                seedValue = seedValue ^ Learmask
            else:
                seedValue = seedValue << 1

        keyValue = seedValue
    else:
        keyValue = 0

    keyValue = keyValue & 0xffffffff
    # print("keyValue:", hex(keyValue))

    key = ()
    for i in range(4):
        key = [keyValue & 0x000000ff,  *key]
        keyValue = keyValue >> 8
    # print("key_hex:", [hex(item) for item in key])

    # 反向排序尝试
    # key = key[::-1]

    return key


def seed_to_key_Qbaic(seed=None, Learmask=None):
    '''
        QBAIC_C230089-2021 UDS安全访问认证技术要求
        Learmask: 16字节密匙因子,16进制表示 0x********
        seed: ECU接收到解锁请求后返回的随机种子,4字节
    '''

    if Learmask is None:
        Learmask = 0x01020304050607080102030405060708.to_bytes(length=16)
    else:
        Learmask = Learmask.to_bytes(length=16)
    # print(Learmask)

    # [ ] 1 使用4字节seed通过SHA256算法产生32字节hash值 seedHash256
    # 随机数，直接用16进制表示
    if seed is None:
        seed = 0x6816b4d5

    # seed转换为byte类型
    seed_byte = seed.to_bytes(length=4)
    # print(seed_byte)
    #
    seed_hash01 = hashlib.sha256(seed_byte)
    seed_hash01_byte = seed_hash01.digest()
    seed_hash01_str = seed_hash01.hexdigest()
    # print(seed_hash01_str)
    # print(seed_hash01_byte)

    # [ ] 2 拼接seedHash256与Learmask，对拼接的值再进行SHA256算法产生32字节Hash值，取前16位作为key_AES128
    seed_hash01_Learmask = seed_hash01_byte+Learmask

    seed_hash02 = hashlib.sha256(seed_hash01_Learmask)
    seed_hash02_str = seed_hash02.hexdigest()
    seed_hash02_byte = seed_hash02.digest()

    # print(seed_hash02_str)
    # print(seed_hash02_byte)

    # [ ] 3 获取seed_hash02_byte的前16位作为密匙k
    seed_key = seed_hash02_byte[:16]
    # print(seed_key)
    print(seed_hash02_str[:32])

    # [ ] 4 使用key_AES128作为秘钥，通过AES128算法(AES128-ECB PKCS5填充)，对seed进行加密，得到16字节的key_unlock
    # aes = AESECB(seed_key)
    aes = AES128_UDS(seed_key)
    # print(aes.encrypt(seed_byte))
    key_unlock = aes.AES_en(seed_byte)
    print(key_unlock)
    print(key_unlock.hex())
    # [ ] 6 将key_unlock返回，后续发回给ECU
    return key_unlock


def main():
    seed_to_key_Qbaic()


if __name__ == '__main__':
    main()
